package saci.util.xml;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;

public class Parser extends XmlReader implements Iterable<Node> {
	
	private String mainTag;
	private HashMap<String, String> mainTagAttributes;
	
    public Parser(InputStream inputStream) throws IOException {
        super(inputStream);
        mainTag = readTag();
    }
    
    protected Parser(String xml, HashMap<String, String> tagMap) {
    	super(xml);
    	super.tagMap = tagMap;
    	mainTag = tagMap.get(TAG_MAP_TAG_NAME);
    	mainTagAttributes = cloneMap();
    }
    
    /**
     * Iterator dos nós principais
     */
    public Iterator<Node> iterator() {
    	return new Iterator<Node>() {
    		boolean readNeeded = true;
    		boolean iterated = false;
    		
			@Override
			public void remove() {
				throw new UnsupportedOperationException();		
			}
		
			@Override
			public Node next() {
				if (readNeeded) {
					readTag();
				}
				readNeeded = true;
				iterated = true;
				Node node = new Node();
				node.setName(tagMap.get(TAG_MAP_TAG_NAME));
				if (!tagMap.containsKey(TAG_MAP_TAG_CLOSE)) { 
					StringBuilder content = new StringBuilder();
					boolean hasChild = readContent(content);
					node.setContent(content.toString());
					node.setHasChild(hasChild);
				}
				node.setAttributes(cloneMap());
				return node;
			}
		
			@Override
			public boolean hasNext() {
				if (iterated && mainTag.equals(tagMap.get(TAG_MAP_TAG_NAME)) && tagMap.containsKey(TAG_MAP_TAG_CLOSE)) {
					return false;
				}
				if (readNeeded) {
					readTag();
					readNeeded = false;
				}
		    	return !isEndTag(mainTag, false);
			}
		};
    }
    
    protected boolean readContent(StringBuilder content) {
    	String tagName = tagMap.get(TAG_MAP_TAG_NAME);
    	String s = super.readContent(tagName);
    	content.append(s);
    	boolean hasChild = s.indexOf("<") > -1;
    	return hasChild;
    }
    
    @SuppressWarnings("unchecked")
	protected HashMap<String, String> cloneMap() {
    	HashMap<String, String> cloneTagMap = (HashMap)tagMap.clone();
    	return cloneTagMap;
    }

	public String getMainTagName() {
		return mainTag;
	}

	public HashMap<String, String> getMainTagAttributes() {
		return mainTagAttributes;
	}

}
